package joq;

import java.util.Observable;

/**
 * An individual message in a queue. Signals any observing SkewHeap instances
 * that it should be deleted on removal from any other queue.
 * @author Jeff Ober<jeffober@gmail.com>
 */
public class Message extends Observable implements Comparable<Message>
{
    private int pri;
    private long timestamp;
    private String msg;

    /**
     * Creates a new message of msg with a priority of pri. A lower integer
     * signifies a higher priority.
     * @param msg A string representing the message (e.g. a serialized object)
     * @param pri A number representing the priority of the job; lower is a higher priority
     */
    Message(String msg, int pri)
    {
	this.msg = msg;
	this.pri = pri;
	timestamp = System.currentTimeMillis();
    }

    /**
     * @return The message contents.
     */
    public String getMessage()
    {
	return msg;
    }

    /**
     * @return The priority of the message.
     */
    public int getPriority()
    {
	return pri;
    }

    /**
     * Used as a tie breaker in compareTo for equal-priority jobs.
     * @return The timestamp, set when the message was created
     */
    public long getTimestamp()
    {
	return timestamp;
    }

    /**
     * Compares two Messages together, first by priority, then by timestamp, for
     * heap ordering.
     * @param o another Message
     * @return 0 when equal, -n when this is greater, +n when o is greater
     */
    public int compareTo(Message o)
    {
	int cmp;
	if ((cmp = pri - o.getPriority()) == 0)
	    return (int) timestamp - (int) o.getTimestamp();
	else
	    return cmp;
    }

    /**
     * Signals listening SkewHeap.Nodes that this Message should be removed.
     */
    public void signalRemoval()
    {
	setChanged();
	notifyObservers(SkewHeap.SIGNAL.DELETE);
	clearChanged();
    }

    /**
     * Returns a nicely formatted string for debugging.
     * @return a debug string
     */
    @Override
    public String toString()
    {
	return "<Message pri=" + pri + " msg=\"" + msg + "\">";
    }
}
